package com.easy.annex.service.impl;

import com.easy.annex.FileModel;
import com.easy.annex.constant.ErrorCode;
import com.easy.annex.repository.FileRepository;
import com.easy.annex.service.IAnnexService;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.gridfs.GridFSBucket;
import com.mongodb.client.gridfs.GridFSBuckets;
import com.mongodb.client.gridfs.GridFSDownloadStream;
import com.mongodb.client.gridfs.model.GridFSFile;
import com.platform.base.utils.Log;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.gridfs.GridFsResource;
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Service
public class AnnexServiceImpl implements IAnnexService {

    @Resource
    private GridFsTemplate gridFsTemplate;

    @Resource
    private MongoTemplate mongoTemplate;

    @Override
    public String uploadFile(MultipartFile file) {
        InputStream ins = null;
        try {
            ins = file.getInputStream();
            ObjectId objectId = gridFsTemplate.store(ins, file.getOriginalFilename(), file.getContentType());
            return objectId.toString();
        } catch (FileNotFoundException fileNotFountException) {
            Log.e(fileNotFountException.getMessage());
            throw new RuntimeException(ErrorCode.UPLOAD_FILE_NOT_FOUNT_EXCEPTION);
        } catch (IOException ioException) {
            Log.e(ioException.getMessage());
            throw new RuntimeException(ErrorCode.UPLOAD_FILE_IO_ERROR);
        } catch (Exception e) {
            Log.e("logException", e);
            throw new RuntimeException(ErrorCode.UPLOAD_FILE_ERROR);
        } finally {
            // 流不为空的时候关闭流
            if (ins != null) {
                try {
                    ins.close();
                } catch (IOException e) {
                    //关闭流的时候如果拋异常的话 先记录日志  再设置返回信息
                    Log.e(e.getMessage());
                }
            }
        }
    }

    @Override
    public List<String> uploadFiles(MultipartFile[] files) {
        List<String> list = new ArrayList<>();
        for (MultipartFile file: files) {
            String fileId = uploadFile(file);
            list.add(fileId);
        }
        return list;
    }

    @Override
    public void downFile(String fileId, HttpServletRequest request, HttpServletResponse response) throws IOException {
        Log.i("文件：{}下载中...", fileId);
        Query query = Query.query(Criteria.where("_id").is(fileId));
        // 查询单个文件
        GridFSFile gridFSFile = gridFsTemplate.findOne(query);
        if (gridFSFile == null) {
            return;
        }

        String fileName = gridFSFile.getFilename().replace(",", "");
        String contentType = gridFSFile.getMetadata().get("_contentType").toString();

        // 通知浏览器进行文件下载
        response.setContentType(contentType);
        response.setHeader("Content-Disposition", "attachment;filename=\"" + URLEncoder.encode(fileName, "UTF-8") + "\"");
        GridFSDownloadStream gridFSDownloadStream = getGridFSBucket().openDownloadStream(gridFSFile.getObjectId());
        GridFsResource resource = new GridFsResource(gridFSFile, gridFSDownloadStream);

        OutputStream outputStream = response.getOutputStream();
        InputStream inputStream = resource.getInputStream();
        IOUtils.copy(inputStream, outputStream);
        outputStream.flush();
        outputStream.close();
        inputStream.close();
    }

    @Override
    public boolean delete(String fileId) {
        List<String> fileIds = new ArrayList<>();
        fileIds.add(fileId);
        return this.batchDelete(fileIds);
    }

    @Override
    public boolean batchDelete(List<String> fileIds) {
        if (fileIds == null || fileIds.size() == 0) {
            throw new RuntimeException(ErrorCode.REQUEST_PARAM_ERROR);
        }
        try{
            Query query = Query.query(Criteria.where("_id").in(fileIds));
            // 查询单个文件
            GridFSFile gridFSFile = gridFsTemplate.findOne(query);
            if (gridFSFile != null) {
                gridFsTemplate.delete(query);
            }
            return true;
        }catch (Exception e){
            Log.e(e.getMessage());
        }
        return false;
    }

    private GridFSBucket getGridFSBucket(){
        MongoDatabase mongoDatabase = mongoTemplate.getDb();
        GridFSBucket bucket = GridFSBuckets.create(mongoDatabase);
        return bucket;
    }
}
